#include <unistd.h>  
#include <sys/socket.h>  
#include <sys/types.h>  
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdio.h>  
#include <errno.h>  
#include <signal.h> 
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <netdb.h>

#define ETH_NAME        "eth0"
#define MAXLINE 100
#define SERV_PORT 9006

int reboot_num = 0;

char BROADCAST_ip[40];
int get_native_ip()
{
    int sock;
	char native_ip[40];
	int bit_ip[4];
        struct sockaddr_in sin;
        struct ifreq ifr;
        
        sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock == -1)
        {
                perror("socket");
                return -1;                
        }
        
        strncpy(ifr.ifr_name, ETH_NAME, IFNAMSIZ);
        ifr.ifr_name[IFNAMSIZ - 1] = 0;
        
        if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
        {
                perror("ioctl");
                
                reboot_num++;
				if(reboot_num>=300)
				{
					system("reboot");
				}
                
                FILE *terminal_fp=fopen("/v4asys/terminal_ip","r");
				memset(native_ip,0,40);
				if(terminal_fp!=NULL)
				{	     
					fgets(native_ip,40,terminal_fp);
					fclose(terminal_fp);
					
					char cmd[40];
					memset(cmd,0,40);
					strcpy(cmd,"ifconfig eth0 ");
					strcat(cmd,native_ip);
					system(cmd);
					printf("%s\n",cmd);
					sleep( 2 );
					system("killall -9 udhpc");
					sleep( 2 );
					system("udhpc");
				}
				else
				{
					close(sock);
					return -1;
				}
        }
        else
        {
			reboot_num=0;
			memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
			sprintf(native_ip, "%s", inet_ntoa(sin.sin_addr));
		}
		
		sscanf(native_ip,"%d.%d.%d.%d",&bit_ip[0],&bit_ip[1],&bit_ip[2],&bit_ip[3]);
		char cmd[40];
		memset(cmd,0,40);
		sprintf(cmd, "route add default gw %d.%d.%d.%d", bit_ip[0],bit_ip[1],bit_ip[2],1);
		system(cmd);
		sprintf(BROADCAST_ip, "%d.%d.%d.%d", bit_ip[0],bit_ip[1],bit_ip[2],255);
		printf("BROADCAST_IP:%s\n",BROADCAST_ip);

        close(sock);
        return 0;
}



int get_server_ip()  
{  
    char buffer[40];
    char server_ip[40];
    char serverip[40];
    int sock = -1;  
    int i;
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)   
    {     
        return 1;  
    }     
    
    struct timeval outtime;
    outtime.tv_sec = 2;
    outtime.tv_usec = 0;
 
    //设置该套接字为广播类型,
    const int opt = 1;
    setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt)); 
    setsockopt(sock, SOL_SOCKET,SO_RCVTIMEO, &outtime,sizeof(outtime));
  
    struct sockaddr_in addrto,addrsv;  
    bzero(&addrto, sizeof(struct sockaddr_in));  
    addrto.sin_family=AF_INET; 
 
    //addrto.sin_addr.s_addr=htonl(BROADCAST_ip);  
    inet_pton(AF_INET, BROADCAST_ip, &addrto.sin_addr);

    addrto.sin_port=htons(9005);  
    int nlen=sizeof(addrto); 
    
    FILE *server_fp=fopen("/v4asys/server_ip","r");
	memset(serverip,0,40);
	if(server_fp!=NULL)
	{	     
		fgets(serverip,40,server_fp);
		fclose(server_fp);
	}
  
    for(i=0;i<5;i++)  
    {  
		if(0!=get_native_ip())
		{
			sleep(5);
			continue;
		}
        inet_pton(AF_INET, BROADCAST_ip, &addrto.sin_addr);
	//从广播地址发送消息
        char smsg[] = {"who is server"};
        sendto(sock, smsg, strlen(smsg), 0, (struct sockaddr*)&addrto, nlen);  
        sleep(3);
	int read_count=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr *)&addrsv,&nlen);  
        if(read_count>0)    
        {         
            sprintf(server_ip,"%s",inet_ntoa(addrsv.sin_addr));
            
            if( strcmp(serverip,server_ip) != 0 )
            {
				FILE *fp=fopen("/v4asys/server_ip","w");
				fwrite(server_ip,strlen(server_ip),1,fp);
				fclose(fp);
			}
			printf("SERVER_IP:%s\n",server_ip);
			close(sock);
			return 0;
        } 
	sleep(5);
    }  
    close(sock);
    return 1;  
}

int checkConnect0(int cnt)  
{   
    int i = 0;   
    FILE *stream;   
    char recvBuf[16] = {0};   
    char cmdBuf[256] = {0};
     
    char serverip[40];
    FILE *server_fp=fopen("/v4asys/server_ip","r");
	memset(serverip,0,40);
	if(server_fp!=NULL)
	{	     
		fgets(serverip,40,server_fp);
		fclose(server_fp);
	}
	else
	{
		server_fp=fopen("/v4asys/server_ip","w");
		fwrite("192.168.2.100",strlen("192.168.2.100"),1,server_fp);
		fclose(server_fp);
		strcpy(serverip,"192.168.2.100");
	}	
  
    if (NULL == serverip || cnt <= 0)   
        return 1;   
  
    sprintf(cmdBuf, "ping %s -c %d | grep time=", serverip, cnt);   
    stream = popen(cmdBuf, "r");   
    fread(recvBuf, sizeof(char), sizeof(recvBuf)-1, stream); 
    printf("%s size=%d\n",recvBuf,strlen(recvBuf));  
    pclose(stream);   
  
    if (strlen(recvBuf) > 0)   
    return 0;   
  
    return 1;   
}

int checkConnect(int cnt)
{
	struct sockaddr_in servaddr;
	char buf[MAXLINE];
	int sockfd, n;
	struct timeval outtime;
	struct hostent *host;
	char dt_cmd[40];
	char serverip[40];
	FILE *server_fp;

	memset(dt_cmd, 0, 40);
	strcpy(dt_cmd, "date 20");

	memset(buf,0,MAXLINE);
	
	server_fp=fopen("/v4asys/server_ip","r");
	memset(serverip,0,40);
	if(server_fp!=NULL)
	{	     
		fgets(serverip,40,server_fp);
		fclose(server_fp);

	}
	else
	{
		return 1;
	}
	
	if(NULL == (host=gethostbyname(serverip)))
	{
		return 1;
	}

	
	if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		printf("time create socket error\n");
		return 1;
	}
	
	outtime.tv_sec = 10;
	outtime.tv_usec = 0;
	setsockopt(sockfd, SOL_SOCKET,SO_RCVTIMEO, &outtime,sizeof(outtime));
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;

	servaddr.sin_addr = *((struct in_addr *)host->h_addr);
	//inet_pton(AF_INET, "192.168.2.117", &servaddr.sin_addr);
	printf("address:%s\n", inet_ntop(AF_INET,host->h_addr, buf, sizeof(buf)));

	servaddr.sin_port = htons(SERV_PORT);
	
	if( connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ){
		printf("connect error\n");
		close(sockfd);
	   	return 1;
	}

	memset(buf,0,MAXLINE);
	if((n = read(sockfd, buf, MAXLINE)) < 16)
	{
		close(sockfd);
		return 1;
	}
	buf[n-3] = '\0';

	buf[2]='.';
	buf[5]='.';
	buf[8]='-';
	buf[11]=':';
	buf[14]=':';

	strcat(dt_cmd,buf);
	system(dt_cmd);
	system("hwclock -w");
	close(sockfd);
	return 0;
	
}

int main()
{
	
	
	int status=0;
	sleep(10);
	
    while(1)
    {
		if(checkConnect(2))//NOT CONNECT
		{
			memset(BROADCAST_ip,0,40);
			get_native_ip();
			status = get_server_ip();	
			if(status == 1)
			{
				system("ifconfig eth0 down");
				sleep(1);
				system("ifconfig eth0 up");
				system("/mnt/bootdev/setmac");
				sleep(1);
				system("killall -2 send_idinfo");
			}
			sleep(600);
		}
		sleep(60);
    }
	return 0;
}
